package com.kyrie.security.interceptor;

import com.alibaba.fastjson.JSON;
import com.kyrie.security.jwt.JWTUtil;
import com.kyrie.utils.ConvertUtils;
import com.kyrie.utils.GlobalConstants;
import com.kyrie.vo.UserInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.Map;

/***
 * 描述: 安全校验拦截器（判断是否为越权访问）,执行在Shiro+jwt认证通过后
 *
 * @author wuxiang
 * @date 2020-04-12 11:59
 */
@Component("ultraViresInterceptor")
public class UltraViresInterceptor extends HandlerInterceptorAdapter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${shiro.anonMappings}")
    private String anonMappings;

    // 拦截前处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
        logger.info("########## 执行自定义安全校验拦截器 ##########");
        try {
            RequestWrapper requestWrapper = new RequestWrapper(request);
            // 获取@RequestBody注解参数和post请求参数
            String body = requestWrapper.getBody();
            String requestUri = request.getRequestURI();
            logger.info("当前请求uri:{},拦截到的请求信息为:{}",requestUri,body);

            if (anonMappings.indexOf(requestUri) > -1) {
                // 请求不做拦截
                return true;
            }
            if (StringUtils.isEmpty(body)) {
                response.sendRedirect("/500?errorMsg=" + URLEncoder.encode(GlobalConstants.CROSS_ACCESS_MSG,"UTF-8"));
                return false;
            }
            Map<String,Object> requestMap = JSON.parseObject(body);
            // 从token中获取用户信息
            UserInfoVO userInfo = ConvertUtils.stringToBean(JWTUtil.getUserInfo(request.getHeader(GlobalConstants.SECURITY_TOKEN)),UserInfoVO.class);
            String userNoFromToken = userInfo.getUserNo();
            String userNoFromRequest = (String) requestMap.get(GlobalConstants.BUSINESS_REQUEST_ID);

            if (StringUtils.isEmpty(userNoFromRequest) || !userNoFromToken.equals(userNoFromRequest)) {
                response.sendRedirect("/500?errorMsg=" + URLEncoder.encode(GlobalConstants.CROSS_ACCESS_MSG,"UTF-8"));
                return false;
            }
            return true;

        } catch (Exception e) {
            logger.error("安全识别请求拦截器内部异常", e);
            return false;
        }
    }

    // 拦截后处理
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
                           ModelAndView modelAndView) throws Exception {

    }

    // 全部完成后处理
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {

    }
}